﻿
Imports std

Public Module _types
    Public Enum typeDefination
        bool = 0
        int
        float
        [string]
        var
        INDEPENDENT_TYPES
        map
        [set]
        vector
        list
        STD_TYPES
        pointer
        TEMPLATE_TYPES

        unknown
    End Enum

    'default type is var
    Public ReadOnly typeNaming() As String = {"bool", "int", "float", "string", "var", "<INVALID>INDEPENDENT_TYPES", _
                                              "map", "set", "vector", "list", "<INVALID>STD_TYPES", _
                                              "pointer", "<INVALID>TEMPLATE_TYPES", _
                                              "<INVALID>UNKNOWN"}

    Public Function isIndependentType(ByVal t As typeDefination) As Boolean
        Return t >= 0 AndAlso t < typeDefination.INDEPENDENT_TYPES
    End Function

    Public Function isTemplateType(ByVal t As typeDefination) As Boolean
        Return isStdType(t) OrElse isPointer(t)
    End Function

    Public Function isStdType(ByVal t As typeDefination) As Boolean
        Return t > typeDefination.INDEPENDENT_TYPES AndAlso t < typeDefination.STD_TYPES
    End Function

    Public Function isPointer(ByVal t As typeDefination) As Boolean
        Return t = typeDefination.pointer
    End Function

    Public Function isUnknownType(ByVal t As typeDefination) As Boolean
        Return t = typeDefination.unknown
    End Function

    Public Function typeEqual(ByVal t As typeDefination, ByVal t2 As typeDefination) As Boolean
        Return t = t2
    End Function

    Public Function matchtype(ByVal t As typeDefination, ByVal t2 As typeDefination) As Boolean
        Return typeEqual(t, t2) OrElse t = typeDefination.var
    End Function

    Public Function matchtype(ByVal t As typeDefination, ByVal i As bare_variable) As Boolean
        Return Not i Is Nothing AndAlso matchtype(t, i.variable().type())
    End Function

    Public Function matchtype(ByVal t As typeDefination, ByVal i As Object) As Boolean
        Return istype(Of bare_variable, Object)(i) AndAlso matchtype(t, convertor.cast(Of bare_variable)(i))
    End Function

    Public MustInherit Class _do_t(Of RT)
        Public MustOverride Function name() As String
    End Class

    Public Class md_t(Of RT)
        Inherits _do_t(Of RT)

        Public NotOverridable Overrides Function name() As String
            Return "map"
        End Function

        Protected Overridable Function cb(Of ET1 As IComparable(Of ET1), ET2) _
                                         (ByRef rtn As RT) As Boolean
            assert(False)
            Return False
        End Function

        Protected Overridable Function cb(Of ET1 As IComparable(Of ET1), ET2) _
                                         (ByRef i As map(Of ET1, ET2), ByRef rtn As RT) As Boolean
            Return cb(Of ET1, ET2)(rtn)
        End Function

        Protected Overridable Function cb(Of ET1 As IComparable(Of ET1), ET2) _
                                         (ByRef i As map(Of ET1, ET2), ByRef rtn As RT, _
                                          ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn)
        End Function

        Public Overridable Function cb(Of ET1 As IComparable(Of ET1), ET2) _
                                      (ByRef i As map(Of ET1, ET2), ByRef rtn As RT, _
                                       ByVal ELEMENTTYPE1 As typeDefination, ByVal ELEMENTTYPE2 As typeDefination, _
                                       ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn, para)
        End Function
    End Class

    Public Class vd_t(Of RT)
        Inherits _do_t(Of RT)

        Public NotOverridable Overrides Function name() As String
            Return "vector"
        End Function

        Protected Overridable Function cb(Of ET) _
                                         (ByRef rtn As RT) As Boolean
            assert(False)
            Return False
        End Function

        Protected Overridable Function cb(Of ET) _
                                         (ByRef i As vector(Of ET), ByRef rtn As RT) As Boolean
            Return cb(Of ET)(rtn)
        End Function

        Protected Overridable Function cb(Of ET) _
                                         (ByRef i As vector(Of ET), ByRef rtn As RT, _
                                          ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn)
        End Function

        Public Overridable Function cb(Of ET) _
                                      (ByRef i As vector(Of ET), ByRef rtn As RT, _
                                       ByVal ELEMENTTYPE As typeDefination, _
                                       ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn, para)
        End Function
    End Class

    Public Class sd_t(Of RT)
        Inherits _do_t(Of RT)

        Public NotOverridable Overrides Function name() As String
            Return "set"
        End Function

        Protected Overridable Function cb(Of ET As IComparable(Of ET)) _
                                         (ByRef rtn As RT) As Boolean
            assert(False)
            Return False
        End Function

        Protected Overridable Function cb(Of ET As IComparable(Of ET)) _
                                         (ByRef i As [set](Of ET), ByRef rtn As RT) As Boolean
            Return cb(Of ET)(rtn)
        End Function

        Protected Overridable Function cb(Of ET As IComparable(Of ET)) _
                                         (ByRef i As [set](Of ET), ByRef rtn As RT, _
                                          ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn)
        End Function

        Public Overridable Function cb(Of ET As IComparable(Of ET)) _
                                      (ByRef i As [set](Of ET), ByRef rtn As RT, _
                                       ByVal ELEMENTTYPE As typeDefination, _
                                       ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn, para)
        End Function
    End Class

    Public Class ld_t(Of RT)
        Inherits _do_t(Of RT)

        Public NotOverridable Overrides Function name() As String
            Return "list"
        End Function

        Protected Overridable Function cb(Of ET) _
                                         (ByRef rtn As RT) As Boolean
            assert(False)
            Return False
        End Function

        Protected Overridable Function cb(Of ET) _
                                         (ByRef i As list(Of ET), ByRef rtn As RT) As Boolean
            Return cb(Of ET)(rtn)
        End Function

        Protected Overridable Function cb(Of ET) _
                                         (ByRef i As list(Of ET), ByRef rtn As RT, _
                                          ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn)
        End Function

        Public Overridable Function cb(Of ET) _
                                      (ByRef i As list(Of ET), ByRef rtn As RT, _
                                       ByVal ELEMENTTYPE As typeDefination, _
                                       ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn, para)
        End Function
    End Class

    Public Class pd_t(Of RT)
        Inherits _do_t(Of RT)

        Public NotOverridable Overrides Function name() As String
            Return "pointer"
        End Function

        Protected Overridable Function cb(Of ET) _
                                         (ByRef rtn As RT) As Boolean
            assert(False)
            Return False
        End Function

        Protected Overridable Function cb(Of ET) _
                                         (ByRef i As pointer(Of ET), ByRef rtn As RT) As Boolean
            Return cb(Of ET)(rtn)
        End Function

        Protected Overridable Function cb(Of ET) _
                                         (ByRef i As pointer(Of ET), ByRef rtn As RT, _
                                          ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn)
        End Function

        Public Overridable Function cb(Of ET) _
                                      (ByRef i As pointer(Of ET), ByRef rtn As RT, _
                                       ByVal ELEMENTTYPE As typeDefination, _
                                       ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn, para)
        End Function
    End Class

    Public Class id_t(Of RT)
        Inherits _do_t(Of RT)

        Public NotOverridable Overrides Function name() As String
            Return "independent"
        End Function

        Protected Overridable Function cb_b(ByRef rtn As RT) As Boolean
            assert(False)
            Return False
        End Function

        Protected Overridable Function cb(ByVal i As Boolean, ByRef rtn As RT) As Boolean
            Return cb_b(rtn)
        End Function

        Protected Overridable Function cb(ByVal i As Boolean, ByRef rtn As RT, _
                                          ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn)
        End Function

        Public Overridable Function cb(ByVal i As Boolean, ByRef rtn As RT, _
                                       ByVal ET As typeDefination, _
                                       ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn, para)
        End Function

        Protected Overridable Function cb_i(ByRef rtn As RT) As Boolean
            assert(False)
            Return False
        End Function

        Protected Overridable Function cb(ByVal i As Int64, ByRef rtn As RT) As Boolean
            Return cb_i(rtn)
        End Function

        Protected Overridable Function cb(ByVal i As Int64, ByRef rtn As RT, _
                                          ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn)
        End Function

        Public Overridable Function cb(ByVal i As Int64, ByRef rtn As RT, _
                                       ByVal ET As typeDefination, _
                                       ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn, para)
        End Function

        Protected Overridable Function cb_d(ByRef rtn As RT) As Boolean
            assert(False)
            Return False
        End Function

        Protected Overridable Function cb(ByVal i As Double, ByRef rtn As RT) As Boolean
            Return cb_d(rtn)
        End Function

        Protected Overridable Function cb(ByVal i As Double, ByRef rtn As RT, _
                                          ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn)
        End Function

        Public Overridable Function cb(ByVal i As Double, ByRef rtn As RT, _
                                       ByVal ET As typeDefination, _
                                       ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn, para)
        End Function

        Protected Overridable Function cb_s(ByRef rtn As RT) As Boolean
            assert(False)
            Return False
        End Function

        Protected Overridable Function cb(ByVal i As String, ByRef rtn As RT) As Boolean
            Return cb_s(rtn)
        End Function

        Protected Overridable Function cb(ByVal i As String, ByRef rtn As RT, _
                                          ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn)
        End Function

        Public Overridable Function cb(ByVal i As String, ByRef rtn As RT, _
                                       ByVal ET As typeDefination, _
                                       ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn, para)
        End Function

        Protected Overridable Function cb_o(ByRef rtn As RT) As Boolean
            assert(False)
            Return False
        End Function

        Protected Overridable Function cb(ByVal i As Object, ByRef rtn As RT) As Boolean
            Return cb_o(rtn)
        End Function

        Protected Overridable Function cb(ByVal i As Object, ByRef rtn As RT, _
                                          ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn)
        End Function

        Public Overridable Function cb(ByVal i As Object, ByRef rtn As RT, _
                                       ByVal ET As typeDefination, _
                                       ByVal ParamArray para() As Object) As Boolean
            Return cb(i, rtn, para)
        End Function

        Protected Overridable Function cb_u(ByRef rtn As RT) As Boolean
            assert(False)
            Return False
        End Function

        Protected Overridable Function cb_u(ByVal i As Object, ByRef rtn As RT) As Boolean
            Return cb_u(rtn)
        End Function

        Protected Overridable Function cb_u(ByVal i As Object, ByRef rtn As RT, _
                                            ByVal ParamArray para() As Object) As Boolean
            Return cb_u(i, rtn)
        End Function

        Public Overridable Function cb_u(ByVal i As Object, ByRef rtn As RT, _
                                         ByVal ET As typeDefination, _
                                         ByVal ParamArray para() As Object) As Boolean
            Return cb_u(i, rtn, para)
        End Function
    End Class

    Private Function validcb(Of RT, T As _do_t(Of RT))(ByVal cb As T) As Boolean
        If cb Is Nothing Then
            raiseError(errorHandle.errorType.warning, "do not have valid ", alloc(Of T)().name(), " callback function.")
            Return False
        End If
        Return True
    End Function

    Private Function cast(Of OT)(ByVal i As Object, ByRef o As OT) As Boolean
        If Not convertor.cast(i, o) Then
            raiseError(errorHandle.errorType.warning, character.null, 1, _
                       "cannot convert input to ", GetType(OT).FullName())
            Return False
        End If
        Return True
    End Function

    Private Function mapInvoke(Of ET1 As IComparable(Of ET1), RT) _
                              (ByVal i As Object, _
                               ByVal ELEMENTTYPE1 As typeDefination, _
                               ByVal ET2 As typeDefination, _
                               ByRef rtn As RT, ByVal md As md_t(Of RT), _
                               ByVal ParamArray para() As Object) As Boolean
        If Not validcb(Of RT, md_t(Of RT))(md) Then
            Return False
        End If
        Select Case ET2
            Case typeDefination.bool
                Dim o As elpmis_map(Of ET1, Boolean) = Nothing
                If Not cast(i, o) Then
                    Return False
                End If
                Return md.cb(+o, rtn, ELEMENTTYPE1, ET2, para)
            Case typeDefination.int
                Dim o As elpmis_map(Of ET1, Int64) = Nothing
                If Not cast(i, o) Then
                    Return False
                End If
                Return md.cb(+o, rtn, ELEMENTTYPE1, ET2, para)
            Case typeDefination.float
                Dim o As elpmis_map(Of ET1, Double) = Nothing
                If Not cast(i, o) Then
                    Return False
                End If
                Return md.cb(+o, rtn, ELEMENTTYPE1, ET2, para)
            Case typeDefination.string
                Dim o As elpmis_map(Of ET1, String) = Nothing
                If Not cast(i, o) Then
                    Return False
                End If
                Return md.cb(+o, rtn, ELEMENTTYPE1, ET2, para)
            Case typeDefination.var
                Dim o As elpmis_map(Of ET1, Object) = Nothing
                If Not cast(i, o) Then
                    Return False
                End If
                Return md.cb(+o, rtn, ELEMENTTYPE1, ET2, para)
            Case Else
                raiseError(errorHandle.errorType.exclamation, "should not have other typeDefination for ET2 ", ET2)
                Return False
        End Select
    End Function

    Private Function mapInvoke(Of RT)(ByVal i As Object, _
                                      ByVal ET1 As typeDefination, ByVal ET2 As typeDefination, _
                                      ByRef rtn As RT, ByVal md As md_t(Of RT), _
                                      ByVal ParamArray para() As Object) As Boolean
        Select Case ET1
            Case typeDefination.bool
                Return mapInvoke(Of Boolean, RT)(i, ET1, ET2, rtn, md, para)
            Case typeDefination.int
                Return mapInvoke(Of Int64, RT)(i, ET1, ET2, rtn, md, para)
            Case typeDefination.float
                Return mapInvoke(Of Double, RT)(i, ET1, ET2, rtn, md, para)
            Case typeDefination.string
                Return mapInvoke(Of String, RT)(i, ET1, ET2, rtn, md, para)
            Case Else
                raiseError(errorHandle.errorType.exclamation, "should not have other typeDefination for ET1 ", ET1)
                Return False
        End Select
    End Function

    Private Function typeInvoke_template(Of ET As IComparable(Of ET), RT) _
                                        (ByVal i As Object, _
                                         ByVal T As typeDefination, _
                                         ByVal ELEMENTTYPE As typeDefination, _
                                         ByRef rtn As RT, _
                                         ByVal vd As vd_t(Of RT), _
                                         ByVal sd As sd_t(Of RT), _
                                         ByVal ld As ld_t(Of RT), _
                                         ByVal pd As pd_t(Of RT), _
                                         ByVal ParamArray para() As Object) As Boolean
        Select Case T
            Case typeDefination.set
                If Not validcb(Of RT, _do_t(Of RT))(sd) Then
                    Return False
                End If
                Dim o As elpmis_set(Of ET) = Nothing
                If Not cast(i, o) Then
                    Return False
                End If
                Return sd.cb(+o, rtn, ELEMENTTYPE, para)
            Case Else
                Return typeInvoke_template_noncomparable(Of ET, RT)(i, T, ELEMENTTYPE, rtn, vd, ld, pd, para)
        End Select
    End Function

    Private Function typeInvoke_template_noncomparable(Of ET, RT) _
                                                      (ByVal i As Object, _
                                                       ByVal T As typeDefination, _
                                                       ByVal ELEMENTTYPE As typeDefination, _
                                                       ByRef rtn As RT, _
                                                       ByVal vd As vd_t(Of RT), _
                                                       ByVal ld As ld_t(Of RT), _
                                                       ByVal pd As pd_t(Of RT), _
                                                       ByVal ParamArray para() As Object) As Boolean
        Select Case T
            Case typeDefination.vector
                If Not validcb(Of RT, vd_t(Of RT))(vd) Then
                    Return False
                End If
                Dim o As elpmis_vector(Of ET) = Nothing
                If Not cast(i, o) Then
                    Return False
                End If
                Return vd.cb(+o, rtn, ELEMENTTYPE, para)
            Case typeDefination.list
                If Not validcb(Of RT, ld_t(Of RT))(ld) Then
                    Return False
                End If
                Dim o As elpmis_list(Of ET) = Nothing
                If Not cast(i, o) Then
                    Return False
                End If
                Return ld.cb(+o, rtn, ELEMENTTYPE, para)
            Case typeDefination.pointer
                If Not validcb(Of RT, pd_t(Of RT))(pd) Then
                    Return False
                End If
                Dim o As elpmis_pointer(Of ET) = Nothing
                If Not cast(i, o) Then
                    Return False
                End If
                Return pd.cb(+o, rtn, ELEMENTTYPE, para)
            Case Else
                raiseError(errorHandle.errorType.warning, "should not have other typeDefination for T ", T)
                Return False
        End Select
    End Function

    Private Function typeInvoke_template(Of RT)(ByVal i As Object, _
                                                ByVal T As typeDefination, ByVal ET1 As typeDefination, _
                                                ByRef rtn As RT, _
                                                ByVal vd As vd_t(Of RT), _
                                                ByVal sd As sd_t(Of RT), _
                                                ByVal ld As ld_t(Of RT), _
                                                ByVal pd As pd_t(Of RT), _
                                                ByVal ParamArray para() As Object) As Boolean
        Select Case ET1
            Case typeDefination.bool
                Return typeInvoke_template(Of Boolean, RT)(i, T, ET1, rtn, vd, sd, ld, pd, para)
            Case typeDefination.int
                Return typeInvoke_template(Of Int64, RT)(i, T, ET1, rtn, vd, sd, ld, pd, para)
            Case typeDefination.float
                Return typeInvoke_template(Of Double, RT)(i, T, ET1, rtn, vd, sd, ld, pd, para)
            Case typeDefination.string
                Return typeInvoke_template(Of String, RT)(i, T, ET1, rtn, vd, sd, ld, pd, para)
            Case typeDefination.var
                Return typeInvoke_template_noncomparable(Of Object, RT)(i, T, ET1, rtn, vd, ld, pd, para)
            Case Else
                raiseError(errorHandle.errorType.warning, "should not have other typeDefination for ET1 ", ET1)
                Return False
        End Select
    End Function

    Public Function typeInvoke_independent(Of RT)(ByVal i As Object, _
                                                  ByVal T As typeDefination, _
                                                  ByRef rtn As RT, _
                                                  ByVal id As id_t(Of RT), _
                                                  ByVal ParamArray para() As Object) As Boolean
        If Not validcb(Of RT, id_t(Of RT))(id) Then
            Return False
        End If
        Select Case T
            Case typeDefination.bool
                Dim o As Boolean = Nothing
                If Not cast(i, o) Then
                    Return False
                End If
                Return id.cb(o, rtn, T, para)
            Case typeDefination.int
                Dim o As Int64 = Nothing
                If Not cast(i, o) Then
                    Return False
                End If
                Return id.cb(o, rtn, T, para)
            Case typeDefination.float
                Dim o As Double = Nothing
                If Not cast(i, o) Then
                    Return False
                End If
                Return id.cb(o, rtn, T, para)
            Case typeDefination.string
                Dim o As String = Nothing
                If Not cast(i, o) Then
                    Return False
                End If
                Return id.cb(o, rtn, T, para)
            Case typeDefination.var
                Dim o As Object = Nothing
                If Not cast(i, o) Then
                    Return False
                End If
                Return id.cb(o, rtn, T, para)
            Case typeDefination.unknown
                Dim o As Object = Nothing
                If Not cast(i, o) Then
                    Return False
                End If
                Return id.cb_u(o, rtn, T, para)
            Case Else
                raiseError(errorHandle.errorType.warning, "should not have other typeDefination for T ", T)
                Return False
        End Select
    End Function

    Public Function typeInvoke(Of RT)(ByVal i As Object, _
                                      ByVal T As typeDefination, _
                                      ByVal ET1 As typeDefination, ByVal ET2 As typeDefination, _
                                      ByRef rtn As RT, _
                                      ByVal md As md_t(Of RT), _
                                      ByVal vd As vd_t(Of RT), _
                                      ByVal sd As sd_t(Of RT), _
                                      ByVal ld As ld_t(Of RT), _
                                      ByVal pd As pd_t(Of RT), _
                                      ByVal id As id_t(Of RT), _
                                      ByVal ParamArray para() As Object) As Boolean
        If T = typeDefination.map Then
            Return mapInvoke(Of RT)(i, ET1, ET2, rtn, md, para)
        ElseIf isTemplateType(T) Then
            Return typeInvoke_template(Of RT)(i, T, ET1, rtn, vd, sd, ld, pd, para)
        Else
            Return typeInvoke_independent(Of RT)(i, T, rtn, id, para)
        End If
    End Function
End Module

Public Class elpmis_pointer(Of T)
    Inherits pointer(Of pointer(Of T))

    Public Sub New()
        MyBase.New(New pointer(Of T)())
    End Sub

    Public Sub New(ByVal i As pointer(Of T))
        MyBase.New(i)
    End Sub
End Class

Public Class elpmis_map(Of T1 As IComparable(Of T1), T2)
    Inherits pointer(Of map(Of T1, T2))

    Public Sub New()
        MyBase.New(New map(Of T1, T2)())
    End Sub

    Public Sub New(ByVal i As map(Of T1, T2))
        MyBase.New(i)
    End Sub
End Class

Public Class elpmis_set(Of T1 As IComparable(Of T1))
    Inherits pointer(Of [set](Of T1))

    Public Sub New()
        MyBase.New(New [set](Of T1)())
    End Sub

    Public Sub New(ByVal i As [set](Of T1))
        MyBase.new(i)
    End Sub
End Class

Public Class elpmis_vector(Of T)
    Inherits pointer(Of vector(Of T))

    Public Sub New()
        MyBase.New(New vector(Of T)())
    End Sub

    Public Sub New(ByVal i As vector(Of T))
        MyBase.New(i)
    End Sub
End Class

Public Class elpmis_list(Of T)
    Inherits pointer(Of list(Of T))

    Public Sub New()
        MyBase.New(New list(Of T)())
    End Sub

    Public Sub New(ByVal i As list(Of T))
        MyBase.new(i)
    End Sub
End Class